/*
 * @Description: 路径相关的一些方法
 * @Author: yilingsj（315800015@qq.com）
 * @Date: 2021-05-01 11:34:10
 * @LastEditors: yilingsj（315800015@qq.com）
 * @LastEditTime: 2021-06-26 17:26:24
 */
const shell = require('shelljs')
var path = require('path')
var fs = require('fs')
/**
 * @author: yilingsj（315800015@qq.com）
 * @description: 判断路径是否存在
 * @param {string} path 路径
 * @return {*}
 * @Date: 2021-05-01 11:34:40
 */
function getStat(path) {
  return new Promise((resolve, reject) => {
    fs.stat(path, (err, stats) => {
      if (err) {
        resolve(false)
      } else {
        resolve(stats)
      }
    })
  })
}

/**
 * @author: yilingsj（315800015@qq.com）
 * @description: 创建目录
 * @param {String} dir 路径
 * @return {*}
 * @Date: 2021-05-01 11:35:26
 */
function mkdir(dir) {
  return new Promise((resolve, reject) => {
    fs.mkdir(dir, (err) => {
      if (err) {
        resolve(false)
      } else {
        resolve(true)
      }
    })
  })
}

/**
 * @author: yilingsj（315800015@qq.com）
 * @description: 路径是否存在，不存在则创建
 * @param {String} dir 路径
 * @return {*}
 * @Date: 2021-05-01 11:37:01
 */
async function dirExists(dir) {
  const isExists = await getStat(dir)
  // 如果该路径且不是文件，返回true
  if (isExists && isExists.isDirectory()) {
    return true
  } else if (isExists) {
    // 如果该路径存在但是文件，返回false
    return false
  }
  // 如果该路径不存在
  const tempDir = path.parse(dir).dir // 拿到上级路径
  // 递归判断，如果上级目录也不存在，则会代码会在此处继续循环执行，直到目录存在
  const status = await dirExists(tempDir)
  let mkdirStatus
  if (status) {
    mkdirStatus = await mkdir(dir)
  }
  return mkdirStatus
}

// 获取当前执行命令
const getRunPresetExec = (env = 'development', type = 'mp-weixin', WEIXIN_PROJECT_PATH = '') => {
  const minimize = env !== 'development' ? '--minimize' : ''
  return `npx cross-env NODE_ENV=${env} UNI_PLATFORM=${type} UNI_OUTPUT_DIR=${WEIXIN_PROJECT_PATH} vue-cli-service uni-build --watch ${minimize} --color=always`
}

let timer = null // 计时器
let beforeTime = null // 统计查找文件需要的时间
let errorNum = 0 // 统计失败的次数
/**
 * @author: yilingsj（315800015@qq.com）
 * @description: 递归查找配置文件是否存在
 * @param {*}
 * @return {*}
 * @Date: 2021-05-01 18:33:54
 */
function findProjectConfig(PROJECT, GLOBAL_CONFIG, WEIXIN_PRESET_PATH, APP_JSON) {
  timer = setTimeout(() => {
    try {
      beforeTime = Date.now()
      const PROJECT_CONFIG = JSON.parse(fs.readFileSync(PROJECT).toString())
      PROJECT_CONFIG.appid = GLOBAL_CONFIG.APPID
      PROJECT_CONFIG.projectname = GLOBAL_CONFIG.TITLE
      PROJECT_CONFIG.setting.enhance = true
      const writeFileStr = JSON.stringify(PROJECT_CONFIG, null, '\t')
      fs.writeFileSync(PROJECT, writeFileStr)
      // 开启直播
      const APP_JSON_CONFIG = JSON.parse(fs.readFileSync(APP_JSON).toString())
      if (GLOBAL_CONFIG.LIVE) {
        APP_JSON_CONFIG.plugins = {
          'live-player-plugin': {
            version: GLOBAL_CONFIG.LIVE_VERSION || '1.0.0',
            provider: GLOBAL_CONFIG.LIVE_PROVIDER || 'wx2b03c6e691cd7370',
          },
        }
      } else {
        if (GLOBAL_CONFIG.VUE_APP_OUTPUTDIR === 'pre' || GLOBAL_CONFIG.VUE_APP_OUTPUTDIR === 'production') {
          const index = APP_JSON_CONFIG.tabBar.list.findIndex((item) => item.text.match('直播'))
          if (index !== -1) {
            APP_JSON_CONFIG.tabBar.list.splice(index, 1)
            console.log('已经删除tabBar中的直播', index)
          }
        }
      }
      const writeFileStr_APP_JSON = JSON.stringify(APP_JSON_CONFIG, null, '\t')
      fs.writeFileSync(APP_JSON, writeFileStr_APP_JSON)
      clearTimeout(timer)
      timer = null
      console.log('已经找到了，耗时：', Date.now() - beforeTime, 'ms', ';', Date.now())
      openDev(WEIXIN_PRESET_PATH)
    } catch (error) {
      errorNum++
      console.log('第' + errorNum + '次还没有找到配置文件', PROJECT)
      if (errorNum < 10) {
        findProjectConfig(PROJECT, GLOBAL_CONFIG, WEIXIN_PRESET_PATH, APP_JSON)
      } else {
        clearTimeout(timer)
        timer = null
        shell.echo('失败次数太多，程序强制停止')
        shell.exit()
      }
    }
  }, 1000)
}
/**
 * @author: yilingsj（315800015@qq.com）
 * @description: 用命令行打开微信小程序
 * @param {*} WEIXIN_PRESET_PATH
 * @return {*}
 * @Date: 2021-05-01 21:38:01
 */
function openDev(WEIXIN_PRESET_PATH) {
  console.log('小程序', Date.now(), ';WEIXIN_PRESET_PATH=', WEIXIN_PRESET_PATH)
  // 打开小程序项目
  const openDevToolsShell = `cli open --project ${WEIXIN_PRESET_PATH} --color=always`
  var childProcess = shell.exec(openDevToolsShell, { async: true })
  childProcess.stdout.on('data', function (data) {
    console.log('小程序stdout: ' + data)
    if (data.match('Error: 错误 ')) {
      console.log('6秒后开始循环刷新', Date.now())
      setTimeout(() => {
        console.log('6秒一刷新，需要重新登录', Date.now())
        openDev(WEIXIN_PRESET_PATH)
      }, 6000)
    }
  })

  childProcess.stderr.on('data', function (data) {
    console.log('小程序 stderr: ' + data)
    if (data.match('wait IDE port timeout')) {
      console.log('再次打开')
      openDev(WEIXIN_PRESET_PATH)
    }
  })
}
module.exports = { getStat, dirExists, getRunPresetExec, findProjectConfig }
